home *** CD-ROM | disk | FTP | other *** search
/ SGI Developer Toolbox 6.1 / SGI Developer Toolbox 6.1 - Disc 4.iso / src / demos / GL / snurb / control.c next >
Encoding:
C/C++ Source or Header  |  1994-08-02  |  13.3 KB  |  679 lines

  1. /*
  2.  * Copyright 1991, 1992, 1993, 1994, Silicon Graphics, Inc.
  3.  * All Rights Reserved.
  4.  *
  5.  * This is UNPUBLISHED PROPRIETARY SOURCE CODE of Silicon Graphics, Inc.;
  6.  * the contents of this file may not be disclosed to third parties, copied or
  7.  * duplicated in any form, in whole or in part, without the prior written
  8.  * permission of Silicon Graphics, Inc.
  9.  *
  10.  * RESTRICTED RIGHTS LEGEND:
  11.  * Use, duplication or disclosure by the Government is subject to restrictions
  12.  * as set forth in subdivision (c)(1)(ii) of the Rights in Technical Data
  13.  * and Computer Software clause at DFARS 252.227-7013, and/or in similar or
  14.  * successor clauses in the FAR, DOD or NASA FAR Supplement. Unpublished -
  15.  * rights reserved under the Copyright Laws of the United States.
  16.  */
  17. #include <stdio.h>
  18. #include <gl.h>
  19. #include <device.h>
  20. #include <math.h>
  21. #include "defines.h"
  22. #include "event.h"
  23. #include "snurb.h"
  24. #include "draw.h"
  25. #include "matrix.h"
  26. #include "menu.h"
  27. #include "pick.h"
  28. #include "rotate.h"
  29. #include "data.h"
  30. #include "scaleobj.h"
  31. #include "rotobj.h"
  32. #include "spaced.h"
  33. #include "nurb.h"
  34. #include "zip.h"
  35. #include "control.h"
  36.  
  37.  
  38.  
  39. /* motion */
  40. Boolean
  41.     moving_control, 
  42.     moving_object, 
  43.     rotating_view, 
  44.     rotating_object, 
  45.     scaling_object,
  46.     zipping;
  47.     
  48. static Coord motion_origin[3];
  49. int move_s,move_t;
  50.  
  51. extern Boolean euler_initialized;
  52.  
  53. /* viewing and projection all in one tidy matrix */
  54. static Matrix everything_matrix;
  55.  
  56. extern Matrix identity_matrix;
  57.  
  58. /* which tool is in use */
  59. int tool;
  60.  
  61. struct node_struct *selected_patch;
  62. extern struct node_struct *root;
  63.  
  64. /* window information */
  65. extern long origin_x, origin_y;
  66. extern long size_x, size_y;
  67. extern float aspect;
  68.  
  69. /* rotation */
  70. extern Matrix view_matrix;
  71. extern Matrix R_view_matrix;
  72.  
  73. /* limits of space editor motion */
  74. Coord spaced_limit[3][2] =
  75.     {    { -1.0, 1.0},
  76.         { -1.0, 1.0},
  77.         { -1.0, 1.0}
  78.     };
  79.  
  80.  
  81. struct node_struct *zip_source, *zip_dest;
  82. int source_s, source_t, dest_s, dest_t;
  83.  
  84.  
  85.  
  86. /* Called every MOUSEX and MOUSEY event, if we are looking for them */
  87. void process_mouse_motion(void)
  88. {
  89.     Coord offset[3];
  90.     Matrix object_matrix;
  91.  
  92.     if (moving_control && getbutton(LEFTMOUSE))
  93.     {
  94.         if (selected_patch != NULL)
  95.         {
  96.             spaced_limit[0][0] = selected_patch->patch->control[move_s][move_t][0] - .2;
  97.             spaced_limit[0][1] = selected_patch->patch->control[move_s][move_t][0] + .2;
  98.  
  99.             spaced_limit[1][0] = selected_patch->patch->control[move_s][move_t][1] - .2;
  100.             spaced_limit[1][1] = selected_patch->patch->control[move_s][move_t][1] + .2;
  101.  
  102.             spaced_limit[2][0] = selected_patch->patch->control[move_s][move_t][2] - .2;
  103.             spaced_limit[2][1] = selected_patch->patch->control[move_s][move_t][2] + .2;
  104.             
  105.  
  106.             
  107.             spaced(everything_matrix,
  108.                 selected_patch->patch->control[move_s][move_t],
  109.                 spaced_limit);
  110.  
  111.             clear_zip_effects(root->child);
  112.             move_zipped_points(selected_patch, move_s, move_t);
  113.  
  114.             clear_zip_effects(root->child);
  115.             move_zipped_points(selected_patch, move_s, move_t);
  116.  
  117.             draw_display();
  118.         }
  119.     }
  120.     else if (moving_object && getbutton(LEFTMOUSE))
  121.     {
  122.         offset[0] = motion_origin[0];
  123.         offset[1] = motion_origin[1];
  124.         offset[2] = motion_origin[2];
  125.  
  126.         spaced_limit[0][0] = motion_origin[0] - .2;
  127.         spaced_limit[0][1] = motion_origin[0] + .2;
  128.         
  129.         spaced_limit[1][0] = motion_origin[1] - .2;
  130.         spaced_limit[1][1] = motion_origin[1] + .2;
  131.         
  132.         spaced_limit[2][0] = motion_origin[2] - .2;
  133.         spaced_limit[2][1] = motion_origin[2] + .2;
  134.         
  135.         spaced(everything_matrix, motion_origin, spaced_limit);
  136.  
  137.         offset[0] = motion_origin[0] - offset[0];
  138.         offset[1] = motion_origin[1] - offset[1];
  139.         offset[2] = motion_origin[2] - offset[2];
  140.  
  141.         pushmatrix();
  142.         loadmatrix(identity_matrix);
  143.         translate(offset[0], offset[1], offset[2]);
  144.         getmatrix(object_matrix);
  145.         popmatrix();
  146.  
  147.         update_selected_children(root->child, object_matrix);
  148.         draw_display();
  149.     }
  150.     else if (rotating_view && getbutton(MIDDLEMOUSE))
  151.     {
  152.         update_view_rotation();
  153.         draw_display();
  154.     }
  155.     else if (rotating_object && getbutton(MIDDLEMOUSE))
  156.     {
  157.         update_object_rotation(object_matrix);
  158.  
  159.         update_selected_children(root->child, object_matrix);
  160.         draw_display();
  161.     }
  162.     else if (scaling_object && getbutton(LEFTMOUSE))
  163.     {
  164.         update_object_scale(object_matrix);
  165.  
  166.         update_selected_children(root->child, object_matrix);
  167.         draw_display();
  168.     }
  169. }
  170.  
  171.  
  172.  
  173.  
  174. void deselect_children(struct node_struct *child)
  175. {
  176.     if (child != NULL)
  177.     {
  178.         child->selected = FALSE;
  179.         deselect_children(child->sibling);
  180.     }
  181. }
  182.  
  183.  
  184.  
  185. /* Where we go on middle down events */
  186. void process_middle_down(void)
  187. {
  188.     Scoord mx,my;
  189.     struct node_struct *selected_object, *rootmost_parent;
  190.  
  191.     /* Mouse position in window screen coords */
  192.     mx = getvaluator(MOUSEX) - (Scoord)origin_x;
  193.     my = getvaluator(MOUSEY) - (Scoord)origin_y;
  194.  
  195.     selected_object = pick_object(mx, my);
  196.     
  197.     if (selected_object == NULL)
  198.     {
  199.         rotating_view = TRUE;
  200.         rotate_view_volume(); 
  201.     }
  202.     else
  203.     {
  204.         if (! (getbutton(LEFTSHIFTKEY) || getbutton(RIGHTSHIFTKEY)))
  205.             deselect_children(root->child);
  206.  
  207.         rootmost_parent = find_rootmost_parent(selected_object);
  208.  
  209.         rootmost_parent->selected = TRUE;
  210.         
  211.         rotating_object = TRUE;
  212.         rotate_object();
  213.     }
  214.  
  215.     qdevice(MOUSEX);
  216.     qdevice(MOUSEY);
  217. }
  218.  
  219.  
  220. /* Where we go on middle up events */
  221. void process_middle_up(void)
  222. {
  223.     unqdevice(MOUSEX);
  224.     unqdevice(MOUSEY);
  225.     
  226.     rotating_view = FALSE;
  227.     rotating_object = FALSE;
  228. }
  229.     
  230.  
  231. /* Where we go on left up events */
  232. void process_left_up(void)
  233. {
  234.     unqdevice(MOUSEX);
  235.     unqdevice(MOUSEY);
  236.  
  237.     moving_control = FALSE;
  238.     moving_object = FALSE;
  239.     scaling_object = FALSE;
  240.     
  241.     end_spaced();
  242.     
  243.     draw_display();
  244. }
  245.  
  246.  
  247. /* Process a left mouse button down event */
  248. void process_left_down(void)
  249. {
  250.     Scoord mx,my;
  251.     struct node_struct *selected_object, *rootmost_parent;
  252.     
  253.  
  254.     /* Mouse position in window screen coords */
  255.     mx = getvaluator(MOUSEX) - (Scoord)origin_x;
  256.     my = getvaluator(MOUSEY) - (Scoord)origin_y;
  257.  
  258.     selected_patch = pick_patch_control(root->child,mx,my,&move_s, &move_t);
  259.  
  260.     if (selected_patch != NULL)
  261.     {
  262.         rootmost_parent = find_rootmost_parent(selected_patch);
  263.  
  264.         if (rootmost_parent->selected)
  265.             set_operation();
  266.         else
  267.         {
  268.             selected_object = pick_object(mx,my);
  269.  
  270.             if (! (getbutton(LEFTSHIFTKEY) || getbutton(RIGHTSHIFTKEY)))
  271.                 deselect_children(root->child);
  272.  
  273.             if (selected_object != NULL)
  274.             {
  275.                 rootmost_parent = find_rootmost_parent(selected_object);
  276.                 rootmost_parent->selected = TRUE;
  277.             }
  278.             else
  279.             {
  280.                 zipping = FALSE;
  281.                 zip_dest = NULL;
  282.             }
  283.         }
  284.     }
  285.     else
  286.     {
  287.         selected_object = pick_object(mx,my);
  288.  
  289.         if (! (getbutton(LEFTSHIFTKEY) || getbutton(RIGHTSHIFTKEY)))
  290.             deselect_children(root->child);
  291.         
  292.         if (selected_object != NULL)
  293.         {
  294.             rootmost_parent = find_rootmost_parent(selected_object);
  295.             rootmost_parent->selected = TRUE;
  296.         }
  297.         else
  298.         {
  299.             zipping = FALSE;
  300.             zip_dest = NULL;
  301.         }
  302.     }
  303.  
  304.     draw_display();
  305. }
  306.  
  307.  
  308. void set_operation()
  309. {
  310.     switch(tool)
  311.     {
  312.         case EDIT_TOOL:
  313.             moving_control = TRUE;
  314.             
  315.             qdevice(MOUSEX);
  316.             qdevice(MOUSEY);
  317.             
  318.             mmode(MSINGLE);
  319.             set_view(MSINGLE);
  320.             multmatrix(view_matrix);
  321.             getmatrix(everything_matrix);
  322.  
  323.             spaced_limit[0][0] = selected_patch->patch->control[move_s][move_t][0] - .2;
  324.             spaced_limit[0][1] = selected_patch->patch->control[move_s][move_t][0] + .2;
  325.  
  326.             spaced_limit[1][0] = selected_patch->patch->control[move_s][move_t][1] - .2;
  327.             spaced_limit[1][1] = selected_patch->patch->control[move_s][move_t][1] + .2;
  328.  
  329.             spaced_limit[2][0] = selected_patch->patch->control[move_s][move_t][2] - .2;
  330.             spaced_limit[2][1] = selected_patch->patch->control[move_s][move_t][2] + .2;
  331.             
  332.             start_spaced();
  333.             break;
  334.             
  335.         case MOVE_TOOL:
  336.             moving_object = TRUE;
  337.             
  338.             motion_origin[0]=selected_patch->patch->control[move_s][move_t][0];
  339.             motion_origin[1]=selected_patch->patch->control[move_s][move_t][1];
  340.             motion_origin[2]=selected_patch->patch->control[move_s][move_t][2];
  341.  
  342.             qdevice(MOUSEX);
  343.             qdevice(MOUSEY);
  344.             
  345.             mmode(MSINGLE);
  346.             set_view(MSINGLE);
  347.             multmatrix(view_matrix);
  348.             getmatrix(everything_matrix);
  349.  
  350.             spaced_limit[0][0] = motion_origin[0] - .2;
  351.             spaced_limit[0][1] = motion_origin[0] + .2;
  352.         
  353.             spaced_limit[1][0] = motion_origin[1] - .2;
  354.             spaced_limit[1][1] = motion_origin[1] + .2;
  355.         
  356.             spaced_limit[2][0] = motion_origin[2] - .2;
  357.             spaced_limit[2][1] = motion_origin[2] + .2;
  358.         
  359.             start_spaced();
  360.             break;
  361.  
  362.         case SCALE_TOOL:
  363.             scaling_object = TRUE;
  364.             
  365.             scale_object();
  366.             
  367.             qdevice(MOUSEX);
  368.             qdevice(MOUSEY);
  369.             break;
  370.  
  371.         case SHARP_ZIP_TOOL:
  372.             process_zip();
  373.             break;
  374.             
  375.         case SMOOTH_ZIP_TOOL:
  376.             process_zip();
  377.             break;
  378.             
  379.         case ROUND_ZIP_TOOL:
  380.             process_zip();
  381.             break;
  382.  
  383.         case UNZIP_TOOL:
  384.             if (inner_edge(move_s,move_t))
  385.                 unzip_edge(selected_patch,find_zip_edge(move_s,move_t));
  386.             break;
  387.         
  388.         default:
  389.             fprintf(stderr,"Uh Oh. Unknown Tool\n");
  390.             break;
  391.             
  392.     }
  393. }
  394.  
  395.  
  396. void process_zip(void)
  397. {
  398.     struct node_struct *source_parent, *dest_parent;
  399.     
  400.     if (! zipping)
  401.     {
  402.         if (inner_edge(move_s,move_t))
  403.         {
  404.             zipping = TRUE;
  405.                 
  406.             zip_dest = selected_patch;
  407.             dest_s = move_s;
  408.             dest_t = move_t;
  409.  
  410.             draw_display();
  411.         }
  412.     }
  413.     else
  414.     {
  415.         if ((selected_patch != zip_dest) && (inner_edge(move_s,move_t)))
  416.         {
  417.             zip_source = selected_patch;
  418.             source_s = move_s;
  419.             source_t = move_t;
  420.  
  421.             clear_zip_effects(root->child);
  422.             
  423.             zip_patches(
  424.                 zip_source,
  425.                 zip_dest,
  426.                 source_s, source_t,
  427.                 dest_s, dest_t,
  428.                 tool);
  429.  
  430.             source_parent = find_rootmost_parent(zip_source);
  431.             dest_parent = find_rootmost_parent(zip_dest);
  432.  
  433.             /* if not already grouped, group 'em */
  434.             if (source_parent != dest_parent)
  435.             {
  436.                 deselect_children(root->child);
  437.                 source_parent->selected = TRUE;
  438.                 dest_parent->selected = TRUE;
  439.                 group();
  440.             }
  441.             
  442.             zipping = FALSE;
  443.             zip_dest = NULL;
  444.         }
  445.     }
  446. }
  447.  
  448.  
  449.  
  450.  
  451.  
  452.  
  453. void update_selected_children(struct node_struct *child, Matrix mat)
  454. {
  455.     if (child != NULL)
  456.     {
  457.         if (child->selected)
  458.             update_control_points(child, mat);
  459.  
  460.         update_selected_children(child->sibling, mat);
  461.     }
  462. }
  463.  
  464.  
  465.  
  466.  
  467. /*********** MENU FUNCTIONS **************/
  468.  
  469.  
  470.  
  471. void set_defaults(void)
  472. {
  473.     tool = MOVE_TOOL;
  474.     selected_patch = NULL;
  475.     deselect_children(root->child);
  476.  
  477.     make_identity(view_matrix);
  478.     make_identity(R_view_matrix);
  479.     euler_initialized = FALSE;
  480.  
  481.     moving_control = 
  482.     moving_object = 
  483.     rotating_view = 
  484.     rotating_object = 
  485.     scaling_object = 
  486.     zipping = FALSE;
  487.  
  488.     selected_patch = zip_dest = NULL;
  489.  
  490.     draw_display();
  491.     
  492.     remake_all_menus();
  493. }
  494.  
  495.  
  496. /*
  497.  * Changes the tool to that selected by the user.
  498.  */
  499. void change_tool(int new_tool)
  500. {
  501.     tool = new_tool;
  502.  
  503.     remake_tool_menu();
  504.     remake_snurb_menu();
  505. }
  506.  
  507.  
  508.  
  509. void delete_selected_children(struct node_struct *child)
  510. {
  511.     struct node_struct *next_child;
  512.     
  513.     if (child != NULL)
  514.     {
  515.         next_child = child->sibling;
  516.         
  517.         if (child->selected)
  518.             free_object(child);
  519.  
  520.         delete_selected_children(next_child);
  521.     }
  522. }
  523.  
  524.  
  525.  
  526. void delete_object(void)
  527. {
  528.     delete_selected_children(root->child);
  529.     
  530.     moving_control = 
  531.     moving_object = 
  532.     rotating_view = 
  533.     rotating_object = 
  534.     scaling_object = 
  535.     zipping = FALSE;
  536.  
  537.     selected_patch = zip_dest = NULL;
  538.  
  539.     draw_display();
  540. }
  541.  
  542.  
  543. void select_all_root_children(struct node_struct *child)
  544. {
  545.     if (child != NULL)
  546.     {
  547.         child->selected = TRUE;
  548.         select_all_root_children(child->sibling);
  549.     }
  550. }
  551.  
  552.  
  553. void select_all(void)
  554. {
  555.     select_all_root_children(root->child);
  556.     draw_display();
  557. }
  558.  
  559.  
  560.  
  561. /* Take all of the root-level nodes that have selected==TRUE and
  562.  * group them beneath one new parent, root-level node
  563.  */
  564. void group(void)
  565. {
  566.     group_selected_children(root);
  567. }
  568.  
  569.  
  570. void ungroup(void)
  571. {
  572.     ungroup_selected_children(root->child);
  573. }
  574.  
  575.  
  576.  
  577.  
  578.  
  579.  
  580.  
  581.  
  582. #ifdef spaceball
  583. /* ================== SPACEBALL INTERFACE ROUTINES ====================== */
  584.  
  585.  
  586. /* ==================== spcbal_do ========================== */
  587. /* This routine is called by sbinteg.c when a Spaceball event has
  588.  * occurred.  This routine will use this information to manipulate
  589.  * a viewing matrix.
  590.  */
  591.  
  592. void spcbal_do(rotvec, rotscale, transvec, transcale)
  593. Coord rotvec[ 3 ];
  594. float rotscale;
  595. Coord transvec[ 3 ];
  596. float transcale;
  597. /*
  598. void spcbal_do(
  599.     Coord rotvec[ 3 ],
  600.     float rotscale,
  601.     Coord transvec[ 3 ],
  602.     float transcale)    DEFINING IT THIS WAY MAKES IT CORE DUMP !! */
  603. {
  604.  
  605.     Matrix    object_matrix;
  606.     int        i;
  607.     Coord center[3];
  608.  
  609.     /* Apply the incremental rotation and translation to the
  610.      * viewing rotation matrix and translation vector
  611.      */
  612.  
  613.     if (root->child != NULL)
  614.     {
  615.         make_identity(object_matrix);
  616.  
  617.         sbMapply( 
  618.             object_matrix,    /* The viewing matrix         */
  619.               (Coord) 1.0,    /* The field of view        */ 
  620.              (Coord) 1.0,     /* The aspect ratio        */
  621.             (Coord) .5,    /* The object radius        */ 
  622.              rotvec,     /* Passed Rotation vector    */
  623.               rotscale,     /* Passed Rotation scale    */
  624.              transvec,    /* Passed Translation vector    */
  625.             transcale    /* Passed Translation scale    */
  626.          );
  627.  
  628.  
  629.         compute_center(center);
  630.  
  631.         loadmatrix(identity_matrix);
  632.         
  633.         translate(center[0],center[1],center[2]); 
  634.         multmatrix(R_view_matrix);
  635.         rotate(450,'y');
  636.         rotate(-450,'x');
  637.         multmatrix(object_matrix);
  638.         rotate(450,'x');
  639.         rotate(-450,'y');
  640.         multmatrix(view_matrix);
  641.         translate(-center[0],-center[1],-center[2]);
  642.  
  643.         
  644.         getmatrix(object_matrix);
  645.  
  646.         update_selected_children(root->child, object_matrix);
  647.  
  648.         draw_display();
  649.     }
  650. }
  651.  
  652.  
  653.  
  654. /* ====================== spchome ====================== */
  655. /* This routine is called when the user requests that the image
  656.  * is reset to the initial position.  This usually means setting
  657.  * the viewing matrix to the identity.
  658.  */
  659. spchome()
  660. {
  661.     Coord center[3];
  662.     Matrix    object_matrix;
  663.  
  664.     compute_center(center);
  665.     
  666.     pushmatrix();
  667.     loadmatrix(identity_matrix);
  668.     translate(-center[0], -center[1], -center[2]);
  669.     getmatrix(object_matrix);
  670.     popmatrix();
  671.  
  672.     update_selected_children(root->child, object_matrix);
  673.     draw_display();
  674.     
  675. }
  676.  
  677. #endif
  678.  
  679.